﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using Microsoft.SharePoint.Client;

namespace SharePointOnlineCmdlets {

    /// <summary>
    /// A WebClient for use with SharePoint Online. 
    /// Constructor takes SharePointOnlineCredentials object and host.
    /// Requests can then be made as an authenticated user.
    /// </summary>
    internal class SPOWebClient : WebClient {

        private readonly string _fedAuthFromSPOCredentials;
        readonly Uri _host;

        CookieContainer _cachedCookieContainer = null;
        DateTime _expires = DateTime.MinValue;

        public SPOWebClient(Uri host, SharePointOnlineCredentials credentials)
        {
            _host = host;
            _fedAuthFromSPOCredentials = credentials.GetAuthenticationCookie(host).Replace("SPOIDCRL=", "");
        }
        
        protected override WebRequest GetWebRequest(Uri address) {
            WebRequest request = base.GetWebRequest(address);
            request.Timeout = 360000;
            if (request is HttpWebRequest) {
                (request as HttpWebRequest).CookieContainer = CookieContainer;
                (request as HttpWebRequest).ServicePoint.Expect100Continue = false;
                (request as HttpWebRequest).ProtocolVersion = HttpVersion.Version11;
            }
            return request;
        }

        #region Cookies
        CookieContainer getCookieContainer() {
            if (_cachedCookieContainer == null || DateTime.Now > _expires) {
                    CookieContainer cc = new CookieContainer();

                    // Set the FedAuth cookie
                    Cookie samlAuth = new Cookie("FedAuth", _fedAuthFromSPOCredentials) {
                        Expires = DateTime.Now.AddHours(3),
                        Path = "/",
                        Secure = _host.Scheme == "https",
                        HttpOnly = true,
                        Domain = _host.Host
                    };
                    cc.Add(samlAuth);

                    _cachedCookieContainer = cc;
                    return cc;
            }
            return _cachedCookieContainer;
        }

        CookieContainer CookieContainer {
            get {
                if (_cachedCookieContainer == null || DateTime.Now > _expires) {
                    return getCookieContainer();
                }
                return _cachedCookieContainer;
            }
        }
        #endregion
    }
}
